using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.Xml;
using Microsoft.Office.Server;
using Microsoft.SharePoint.WebControls;
using Microsoft.Office.Server.ApplicationRegistry.Runtime;
using Microsoft.Office.Server.ApplicationRegistry.MetadataModel;

namespace MacroView.SharePointFields
{
    public class clsBDCLookUpPicker : System.Web.UI.Page 
    {
        TextBox txtQuery;
        System.Web.UI.ScriptManager ajaxScriptManager;
        DropDownList cboFinders;
        Image imgSearch;
        ImageButton btnGoSearch;
        Table tblFormat;
        DataGrid gdResults;
        SPGridView gvResults;
        System.Web.UI.WebControls.Panel pnlSearch;
        System.Web.UI.UpdatePanel dvUpdatePanel;
        System.Web.UI.UpdatePanel dvOKUpdatePanel;
        Button btnOK;
        Label lblErrorLabel;

        protected Microsoft.SharePoint.WebControls.PickerDialog MVPickerControl;

        private void EnsureUpdatePanelFixups()
        {
            if (this.Page.Form != null)
            {
                string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
                if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
                {
                    this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
                }
            }
            System.Web.UI.ScriptManager.RegisterStartupScript(this, typeof(clsBDCLookUpPicker), "UpdatePanelFixup", "_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;", true);
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            try
            {
                
                PlaceHolder QueryArea = (PlaceHolder)Page.FindControl("ctl00$PlaceHolderDialogBodySection$PlaceHolderQueryControl");
                PlaceHolder ResultsArea = (PlaceHolder)Page.FindControl("ctl00$PlaceHolderDialogBodySection$PlaceHolderResultControl");
                PlaceHolder PlaceHolderOK = (PlaceHolder)Page.FindControl("ctl00$PlaceHolderDialogButtonSection$PlaceHolderOKButton");

                dvUpdatePanel = new System.Web.UI.UpdatePanel();

                ajaxScriptManager = new System.Web.UI.ScriptManager();
                ajaxScriptManager.EnablePartialRendering = true;
                QueryArea.Controls.Add(ajaxScriptManager);

                EnsureUpdatePanelFixups();

                dvOKUpdatePanel = new System.Web.UI.UpdatePanel();

                btnOK = new Button();
                btnOK.ID = "btnOK";
                btnOK.Text = "OK";
                btnOK.CssClass = "ms-ButtonHeightWidth";

                dvOKUpdatePanel.ContentTemplateContainer.Controls.Add(btnOK);
                dvOKUpdatePanel.UpdateMode = System.Web.UI.UpdatePanelUpdateMode.Conditional;
                dvOKUpdatePanel.ChildrenAsTriggers = true;

                PlaceHolderOK.Controls.Add(dvOKUpdatePanel);
                
                tblFormat = new Table();
                tblFormat.BorderWidth = 0;
                tblFormat.CellPadding = 0;
                tblFormat.CellSpacing = 0;
                tblFormat.Style.Add("width", "100%");

                cboFinders = new DropDownList();
                btnGoSearch=new ImageButton();

                XmlDocument finders = GetBDCFinders(Request["BDCApplication"], Request["BDCEntity"]);
                XmlNamespaceManager dmfNameSpaceMgr = new XmlNamespaceManager(finders.NameTable);
                dmfNameSpaceMgr.AddNamespace("dmf", "http://www.macroview.com.au/DMF/MessageServer");
                foreach (XmlNode currentFinder in finders.SelectNodes("//dmf:finder", dmfNameSpaceMgr))
                {
                    ListItem newItem = new ListItem(currentFinder.Attributes.GetNamedItem("displayname").Value, currentFinder.Attributes.GetNamedItem("name").Value);
                    cboFinders.Items.Add(newItem);
                }

                cboFinders.Style.Add("height", "20px");
                TableRow rSearchBox = new TableRow();
                rSearchBox.BorderWidth = 0;

                Image imgBlank = new Image();
                imgBlank.ImageUrl = "/_layouts/images/blank.gif";

                TableCell cSearchText = new TableCell();
                cSearchText.BorderWidth = 0;
                cSearchText.CssClass = "ms-descriptiontext";
                cSearchText.Style.Add("font-weight", "bold");
                cSearchText.Text = "Find";
                rSearchBox.Controls.Add(cSearchText);

                TableCell cSearchSpacer = new TableCell();
                cSearchSpacer.BorderWidth = 0;
                cSearchSpacer.CssClass = "ms-descriptiontext";
                imgBlank.Style.Add("width", "10px");
                cSearchSpacer.Controls.Add(imgBlank);
                rSearchBox.Controls.Add(cSearchSpacer);

                TableCell cSearchEntity = new TableCell();
                cSearchEntity.Style.Add("height", "20px !important");
                cSearchEntity.VerticalAlign = VerticalAlign.Middle;
                cSearchEntity.Controls.Add(cboFinders);
                cSearchEntity.BorderWidth = 0;
                rSearchBox.Cells.Add(cSearchEntity);

                TableCell cSearchBox = new TableCell();
                cSearchBox.BorderWidth = 0;
                
                txtQuery = new TextBox();

                txtQuery.Style.Add("width", "100%");
                txtQuery.Style.Add("border","solid 1px #7f9db9");
                txtQuery.Style.Add("border-right","none");
                txtQuery.Style.Add("color","#1952a4");
                txtQuery.Style.Add("font-family","Verdana");
                txtQuery.Style.Add("font-size","8pt");
                txtQuery.Style.Add("height","21px !important");
                txtQuery.Style.Add("padding-top","2px");
                txtQuery.Style.Add("padding-left", "2px");

                cSearchBox.Style.Add("width", "100%");
                cSearchBox.Controls.Add(txtQuery);

                rSearchBox.Cells.Add(cSearchBox);
                tblFormat.Rows.Add(rSearchBox);

                QueryArea.Controls.Add(tblFormat);

                TableCell cSearchImage = new TableCell();
                cSearchImage.VerticalAlign = VerticalAlign.Middle;

                pnlSearch = new Panel();
                pnlSearch.Style.Add("border", "solid 1px #7f9db9");
                pnlSearch.Style.Add("border-left", "solid 1px #9ed6ff");
                pnlSearch.Style.Add("background-color", "#e9f2fd");
                pnlSearch.Style.Add("padding-left", "3px");
                pnlSearch.Style.Add("padding-right", "3px");
                pnlSearch.Style.Add("height", "21px !important");
                pnlSearch.Style.Add("padding-bottom", "0px"); //!important;
                pnlSearch.Style.Add("padding-top", "0px"); //!important;

                btnGoSearch.ImageUrl = "/_layouts/images/gosearch.gif";
                btnGoSearch.ID = "btnGoSearch";

                btnGoSearch.Click += new System.Web.UI.ImageClickEventHandler(btnGoSearch_Click);
                
                pnlSearch.Controls.Add(btnGoSearch);
                cSearchImage.Controls.Add(pnlSearch);

                rSearchBox.Cells.Add(cSearchImage);

                System.Web.UI.AsyncPostBackTrigger uptTrigger=new System.Web.UI.AsyncPostBackTrigger();
                uptTrigger.ControlID = btnGoSearch.UniqueID;
                uptTrigger.EventName = "Click";
                dvUpdatePanel.Triggers.Add(uptTrigger);

                gvResults = new SPGridView();
                gvResults.ID="gvResults";
                gvResults.AutoGenerateColumns = false;

                gvResults.RowCreated += new GridViewRowEventHandler(gvResults_RowCreated);
                gvResults.SelectedIndexChanged += new EventHandler(gvResults_SelectedIndexChanged);
                
                dvUpdatePanel.UpdateMode = System.Web.UI.UpdatePanelUpdateMode.Conditional;
                dvUpdatePanel.ChildrenAsTriggers = true;
                dvUpdatePanel.ContentTemplateContainer.Controls.Add(gvResults);

                ResultsArea.Controls.Add(dvUpdatePanel);

                lblErrorLabel = new Label();
                ResultsArea.Controls.Add(lblErrorLabel);

            }
            catch (Exception ex)
            { }

        }

        void gvResults_SelectedIndexChanged(object sender, EventArgs e)
        {
            gvResults.SelectedRowStyle.CssClass = "ms-pb-selected";
            gvResults.SelectedRowStyle.Font.Bold = false;

            btnOK.OnClientClick = "javascript:try { window.opener.document.getElementById('" + Page.Request["returnfield"] + "').value='" + gvResults.SelectedDataKey[Request["BDCReturnField"].ToUpper()].ToString() + "';window.close();return false;} catch (e) { alert(e.description);window.close();return false;}";

            dvOKUpdatePanel.Update(); 
        }

        void gvResults_RowCreated(object sender, GridViewRowEventArgs e)
        {
            int currentIndex = e.Row.DataItemIndex;
            foreach (TableCell currentCell in e.Row.Cells)
            {

                currentCell.Attributes.Add("onmouseover",
                       "this.style.cursor='pointer'");

                currentCell.Attributes.Add("onclick", "javascript:__doPostBack" +
                       "('" + gvResults.ClientID.Replace("_","$") + "','Select$" + e.Row.DataItemIndex.ToString() + "')");
            }

        }

        void btnGoSearch_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {

            try
            {
                gvResults.DataSource = QueryBDC(Request["BDCApplication"], Request["BDCEntity"], txtQuery.Text, Request["ReturnField"], cboFinders.SelectedValue.ToString()).Tables[0];
                string[] keys = Request["DisplayFields"].ToUpper().Split(',');
                gvResults.DataKeyNames = keys;

                gvResults.Columns.Clear();
                foreach (DataColumn currentCol in ((DataTable)gvResults.DataSource).Columns)
                {
                    //ADRH 17/12/2007 - Ignore BDCIdentifier column in the results.
                    if (currentCol.ColumnName.ToString() != "BDCIdentifier")
                    {
                        BoundField newfield = new BoundField();
                        newfield.HeaderText = currentCol.Caption.ToString();
                        newfield.DataField = currentCol.ColumnName.ToString();
                        gvResults.Columns.Add(newfield);
                    }
                }

                gvResults.DataBind();
            }
            catch (Exception exSearch)
            {
                lblErrorLabel.Text = exSearch.Message.ToString();
            }

            try
            {
                btnOK.OnClientClick = "javascript:try { window.opener.document.getElementById('" + Page.Request["returnfield"] + "').value='" + gvResults.SelectedDataKey[Request["BDCReturnField"].ToUpper()].ToString() + "';window.close();return false;} catch (e) { alert(e.description);window.close();return false;}";
            }
            catch (Exception jsEx) { }
            
        }

        public XmlDocument GetBDCFinders(string sLOBInstanceName, string sEntity)
        {
            XmlDocument xmlFinders = new XmlDocument();

            try
            {
                NamedLobSystemInstanceDictionary sysInstances = ApplicationRegistry.GetLobSystemInstances();
                LobSystemInstance myIns = sysInstances[sLOBInstanceName];
                Entity myEntity = myIns.GetEntities()[sEntity];
                FilterCollection fc = myEntity.GetFinderFilters();

                XmlNode xmlTopNode = xmlFinders.CreateNode(XmlNodeType.Element, "finders", "http://www.macroview.com.au/DMF/MessageServer");
                xmlFinders.AppendChild(xmlTopNode);

                foreach (FilterDescriptor currentFilter in myEntity.GetFinderMethodInstance().GetMethod().GetFilterDescriptors())
                {
 
                    XmlNode xmlFinderNode = xmlFinders.CreateNode(XmlNodeType.Element, "finder", "http://www.macroview.com.au/DMF/MessageServer");
                    XmlAttribute xmlAttrName = xmlFinders.CreateAttribute("name");
                    xmlAttrName.Value = currentFilter.Name;
                    xmlFinderNode.Attributes.Append(xmlAttrName);
                    try
                    {
                        XmlAttribute xmlAttrDisplayName = xmlFinders.CreateAttribute("displayname");
                        xmlAttrDisplayName.Value = currentFilter.GetDefaultDisplayName();
                        xmlFinderNode.Attributes.Append(xmlAttrDisplayName);
                    }
                    catch (Exception attrex)
                    {
                        //Ignore as we will use the name on the client.
                    }
                    xmlTopNode.AppendChild(xmlFinderNode);
                }

                return xmlFinders;
            }
            catch (Exception ex)
            {
                return xmlFinders;
            }
        }

        public DataSet QueryBDC(string sLOBInstanceName, string sEntity, string sQueryString, string sFieldName, string sFinderName)
        {
            DataSet Resultset = new DataSet();

            try
            {

                NamedLobSystemInstanceDictionary sysInstances = ApplicationRegistry.GetLobSystemInstances();
                LobSystemInstance myIns = sysInstances[sLOBInstanceName];
                Entity myEntity = myIns.GetEntities()[sEntity];
                FilterCollection fc = myEntity.GetFinderFilters();
                for (int i = 0; i < fc.Count; i++)
                {
                    if (fc[i].Name == sFinderName || sFinderName == "")
                    {
                        switch (fc[i].GetType().FullName)
                        {
                            case "Microsoft.Office.Server.ApplicationRegistry.Runtime.WildcardFilter":
                                ((WildcardFilter)fc[i]).SystemIndependentValue = "*" + sQueryString + "*";
                                break;
                            case "Microsoft.Office.Server.ApplicationRegistry.Runtime.ComparisonFilter":
                                ((ComparisonFilter)fc[i]).Value = Convert.ChangeType(sQueryString, ((ComparisonFilter)fc[i]).GetFilterValueType());
                                break;
                            case "Microsoft.Office.Server.ApplicationRegistry.Runtime.LimitFilter":
                                ((LimitFilter)fc[i]).Value = Math.Min(0xc9, ((LimitFilter)fc[i]).MaximumValue);
                                break;
                        }
                    }
                }

                IEntityInstanceEnumerator prodEntityInstanceEnumerator = myEntity.FindFiltered(fc, myIns);

                DataTable Results = new DataTable("BDCData");
                Resultset.Tables.Add(Results);

                //Get the collection of IDs and create an array to store their names.
                IdentifierCollection EntIDS = myEntity.GetIdentifiers();
                string[] sIDNames = new string[EntIDS.Count];

                //Get the names.
                int nCounter = 0;

                foreach (Identifier currentID in EntIDS)
                {
                    sIDNames[nCounter] = currentID.Name;
                    nCounter++;
                }

                string sTitle = "";
                //Resultset.Tables.Add(IE.EntityAsDataTable);
                if (myEntity.GetProperties().ContainsKey("Title"))
                {
                    sTitle = myEntity.GetProperties()["Title"].ToString();
                }

                Boolean blnShowInPickers = false;
                foreach (Field f in myEntity.GetFinderView().Fields)
                {
                    if (f.TypeDescriptor.GetProperties().ContainsKey("ShowInPicker"))
                    {
                        if (((Boolean)f.TypeDescriptor.GetProperties()["ShowInPicker"]))
                        {
                            blnShowInPickers = true;
                        }
                    }
                }

                DataColumn currentColumn = null;
                foreach (Field f in myEntity.GetFinderView().Fields)
                {
                    if (f.DefaultDisplayName == "")
                    {
                        currentColumn = Results.Columns.Add(f.Name);
                    }
                    else
                    {
                        currentColumn = Results.Columns.Add(f.Name);
                        currentColumn.Caption = f.DefaultDisplayName;
                    }

                    if (blnShowInPickers)
                    {
                        if (f.Name != sTitle)
                        {
                            if (f.TypeDescriptor.GetProperties().ContainsKey("ShowInPicker"))
                            {
                                if (((Boolean)f.TypeDescriptor.GetProperties()["ShowInPicker"]))
                                {
                                    currentColumn.ExtendedProperties.Add("ShowInPicker", "TRUE");
                                }
                                else
                                {
                                    currentColumn.ExtendedProperties.Add("ShowInPicker", "FALSE");
                                }
                            }
                        }
                        else
                        {
                            currentColumn.ExtendedProperties.Add("ShowInPicker", "TRUE");
                        }
                    }
                    else
                    {
                        if (f.TypeDescriptor.ContainsIdentifier || f.Name == sTitle)
                        {
                            currentColumn.ExtendedProperties.Add("ShowInPicker", "TRUE");
                        }
                        else
                        {
                            currentColumn.ExtendedProperties.Add("ShowInPicker", "FALSE");
                        }
                    }
                }

                //Now add a column for the BDCID.
                Results.Columns.Add("BDCIdentifier");

                while (prodEntityInstanceEnumerator.MoveNext())
                {
                    try
                    {
                        IEntityInstance IE = prodEntityInstanceEnumerator.Current;
                        DataRow newResultRow = Results.NewRow();

                        //WriteToFile(IE.GetHashCode().ToString() , "");
                        //WriteToFile(IE.ToString() , "");
                        System.Collections.IList MyList = (System.Collections.IList)IE.GetIdentifierValues();

                        //Create an array to hold the identifiers.
                        object[] oIdentitiers = new object[sIDNames.Length];

                        for (int i = 0; i < MyList.Count; i++)
                        {
                            oIdentitiers[i] = MyList[i].ToString();
                        }

                        //Encode the ID's to give the BDC identifier.
                        string sEntitiesID = Microsoft.Office.Server.ApplicationRegistry.Infrastructure.EntityInstanceIdEncoder.EncodeEntityInstanceId(oIdentitiers);

                        //Add the ID to the resultset.
                        newResultRow["BDCIdentifier"] = sEntitiesID;

                        foreach (Field f in myEntity.GetFinderView().Fields)
                        {
                            try
                            {
                                if (IE[f] != null)
                                {
                                    newResultRow[f.Name] = IE[f];
                                }
                            }
                            catch (Exception colex)
                            {
                            }
                        }
                        Results.Rows.Add(newResultRow);
                    }
                    catch (Exception rowex)
                    {

                    }
                }

                return Resultset;

            }
            catch (Exception ex)
            {
                return Resultset;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

        }
    }
}
